

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';

class UnLockPage extends StatefulWidget {
  const UnLockPage({Key key}) : super(key: key);
  @override
  _UnLockPageState createState() => _UnLockPageState();
}

enum AuthStatus{
  IN_AUTH,
  FAIL_BIOMETRICS_AUTH,
  FAIL_PWD_AUTH,
  SUCCESS_BIOMETRICS_AUTH,
  SUCCESS_PWD_AUTH
}

class _UnLockPageState extends State<UnLockPage>  with TickerProviderStateMixin {

  static final int MAX_COUNT = 6;

  List<String> _unlockPwd = [];

  String _userPwdStr = '';

  bool _enableKeyBord = true;

  AuthStatus _authStatus = AuthStatus.IN_AUTH;

  final LocalAuthentication auth = LocalAuthentication();

  AnimationController animationController;

  Animation _animation;

  static final double MAX_ANIM_PADDING = 20;

  static final List<double> paddingList = [
    0,
     -MAX_ANIM_PADDING,
    0,
    MAX_ANIM_PADDING,
    0,
    -MAX_ANIM_PADDING,
    0,
    MAX_ANIM_PADDING,
    0,
    -MAX_ANIM_PADDING,
    0
  ];

  double _getPaddingByAnim(double value){
    var bottom = paddingList[value.floor()];
    var top = paddingList[value.ceil()];
    var point = value - value.floor();
    // 取值方法，我也不知道咋来的
    var animValue  = bottom - point * (bottom - top);
    return animValue;
  }

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(duration: Duration(milliseconds: 1000), vsync: this)..addStatusListener((status) {
      if(status == AnimationStatus.forward){
        _enableKeyBord = false;
      }
      if(status == AnimationStatus.completed){
        _enableKeyBord = true;
      }
      if(status == AnimationStatus.dismissed){
        _enableKeyBord = true;
      }
    });
    _animation = Tween(begin: 0.0, end: (paddingList.length -1).toDouble()).chain(CurveTween(curve: Curves.easeInOut)).animate(animationController);
    _getPwd();
  }

  _getPwd()async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _userPwdStr = (prefs.getString('_unlock_pwd') ?? '123456');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
          appBar: AppBar(
            title: Text('解锁'),
          ),
          body: new Builder(builder: (BuildContext ctx){
            return Container(
                color: Color(0xfff5f5f5),
                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 5),
                height: double.infinity,
                width: double.infinity,
                child: Column(
                  children: [
                    Container(
                      height: 100,
                      width: double.infinity,
                      decoration: BoxDecoration(
                          color: Color(0xffeeeeee),
                          borderRadius: BorderRadius.all(Radius.circular(5.0))
                      ),
                      alignment: Alignment.center,
                      child: AnimatedBuilder(
                        animation: _animation,
                        builder: (BuildContext context, Widget child) {
                          return Transform.translate(
                            offset: Offset(_getPaddingByAnim(_animation.value),0),
                            child: child,
                          );
                        },
                        child: ListView.builder(
                          shrinkWrap: true,
                          physics:NeverScrollableScrollPhysics(),
                          itemCount: MAX_COUNT,
                          scrollDirection: Axis.horizontal,
                          itemBuilder: (ctx,index){
                            return Container(
                              alignment: Alignment.center,
                              child: AnimatedCrossFade(
                                duration: Duration(milliseconds: 300),
                                crossFadeState:_unlockPwd.length <= index ? CrossFadeState.showFirst : CrossFadeState.showSecond,
                                firstChild: Icon(Icons.panorama_fish_eye,size: 20,),
                                secondChild: Icon(Icons.circle,size: 20,),
                              ),
                            );
                          }
                        )
                      )
                    ),
                    _pwdTrip(),
                    Container(
                        margin: EdgeInsets.only(top: 20.0),
                        // height: 430,
                        width: 300,
                        child: Material(
                            color: Colors.transparent,
                            child: GridView(
                              shrinkWrap: true,
                              physics:NeverScrollableScrollPhysics(),
                              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                                  crossAxisCount: 3,
                                  crossAxisSpacing: 10.0,
                                  mainAxisSpacing: 10.0
                              ),
                              children: [
                                _createGridViewItem('1',ctx),
                                _createGridViewItem('2',ctx),
                                _createGridViewItem('3',ctx),
                                _createGridViewItem('4',ctx),
                                _createGridViewItem('5',ctx),
                                _createGridViewItem('6',ctx),
                                _createGridViewItem('7',ctx),
                                _createGridViewItem('8',ctx),
                                _createGridViewItem('9',ctx),
                                _createBtnGridViewItem(Icons.clear,(){
                                  setState(() {
                                    _authStatus = AuthStatus.IN_AUTH;
                                    _unlockPwd.clear();
                                  });
                                }),
                                _createGridViewItem('0',ctx),
                                _createBtnGridViewItem(_unlockPwd.isNotEmpty?Icons.delete:Icons.fingerprint_sharp,(){
                                  setState(() {
                                    _authStatus = AuthStatus.IN_AUTH;
                                    if(_unlockPwd.isNotEmpty){
                                      _unlockPwd.removeLast();
                                    }else{
                                      _authenticate();
                                    }
                                  });
                                })
                              ],
                            )
                        )
                    )
                  ],
                )
            );
          })
      );
  }

  Widget _createGridViewItem(String number,BuildContext ctx){
    return  Ink(
        decoration: BoxDecoration(
            color: Color(0xffE1FFFF),
            border: Border.all(color: Color(0xff87CEFA), width: 1),//边框
            borderRadius: BorderRadius.all(Radius.circular(50.0))
        ),
        child:  InkWell(
          splashColor: Colors.blueAccent,
          borderRadius: BorderRadius.all(Radius.circular(50)),
          onTap: () {
            if(_unlockPwd.length == MAX_COUNT){
              return;
            }
            if(!_enableKeyBord){
              return;
            }
            setState(() {
              _unlockPwd.add(number);
              _authStatus = AuthStatus.IN_AUTH;
              if(_unlockPwd.length == MAX_COUNT){
                if(_unlockPwd.join('') == _userPwdStr){
                  _authStatus = AuthStatus.SUCCESS_PWD_AUTH;
                  Navigator.of(context).pushReplacementNamed('/mainPage');
                }else{
                  _authStatus = AuthStatus.FAIL_PWD_AUTH;
                  animationController.reset();
                  animationController.forward();
                  _unlockPwd.clear();
                }
              }
            });
          },
          child: Center(
            child: Text(number,style: TextStyle(fontSize: 18.0)),
          )
        )
    );
  }

  _createBtnGridViewItem(IconData icon,onTap){
    return Ink(
      decoration: BoxDecoration(
          color: Colors.blueAccent,
          border: Border.all(color: Colors.lightBlue, width: 1),//边框
          borderRadius: BorderRadius.all(Radius.circular(50.0))
      ),
      child:  InkWell(
        borderRadius: BorderRadius.all(Radius.circular(50)),
        onTap: onTap,
        child: Center(
            child: Icon(icon,size: 30,color: Colors.white)
        ),
      ),
    );
  }

  Widget _pwdTrip(){
    Icon icon;
    Text text;
    switch(_authStatus){
      case AuthStatus.IN_AUTH:
        icon = Icon(Icons.fingerprint,color: Colors.black45,size: 30);
        text = Text('输入密码或指纹',style: TextStyle(color: Colors.black45,fontSize: 18.0));
        break;
      case AuthStatus.FAIL_BIOMETRICS_AUTH:
        icon = Icon(Icons.fingerprint,color: Colors.red,size: 30);
        text = Text('指纹验证失败，请重试',style: TextStyle(color: Colors.red,fontSize: 18.0));
        break;
      case AuthStatus.FAIL_PWD_AUTH:
        icon = Icon(Icons.close,color: Colors.red,size: 30);
        text = Text('密码验证失败，请重新输入',style: TextStyle(color: Colors.red,fontSize: 18.0));

        break;
      case AuthStatus.SUCCESS_BIOMETRICS_AUTH:
        icon = Icon(Icons.fingerprint,color: Colors.green,size: 30);
        text = Text('验证成功',style: TextStyle(color: Colors.green,fontSize: 18.0));
        break;
      case AuthStatus.SUCCESS_PWD_AUTH:
        icon = Icon(Icons.check,color: Colors.green,size: 30);
        text = Text('验证成功',style: TextStyle(color: Colors.green,fontSize: 18.0));
        break;
    }
    return Container(
        margin: EdgeInsets.only(top: 10),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            icon,
            VerticalDivider(width: 5),
            text
          ],
        )
    );
  }


  /// 生物识别
  Future<Null> _authenticate() async {
    bool canCheckBiometrics = await auth.canCheckBiometrics;
    if(canCheckBiometrics){
      List<BiometricType> availableBiometrics =
      await auth.getAvailableBiometrics();

      if (availableBiometrics.contains(BiometricType.face)) {
        // Face ID.
      } else if (availableBiometrics.contains(BiometricType.fingerprint)) {
        const andStrings = const AndroidAuthMessages(
          cancelButton: '取消',
          goToSettingsButton: '去设置',
          goToSettingsDescription: '请设置指纹.',
          signInTitle: '密码记事本',
          biometricHint: "解锁指纹",
          biometricNotRecognized: 'biometricNotRecognized',
          biometricRequiredTitle: 'biometricRequiredTitle',
          biometricSuccess: 'biometricSuccess',
          deviceCredentialsRequiredTitle: 'deviceCredentialsRequiredTitle',
          deviceCredentialsSetupDescription: 'deviceCredentialsSetupDescription'
        );
        auth.authenticate(
            localizedReason: '扫描指纹进行身份验证',
            biometricOnly: true,
            stickyAuth: true,
            useErrorDialogs: false,
            androidAuthStrings :andStrings
        )
            .then((result) => {
                  if(result){
                      setState(() {
                        _authStatus = AuthStatus.SUCCESS_BIOMETRICS_AUTH;
                        Navigator.of(context).pushReplacementNamed('/mainPage');
                      })
                  }else{
                    setState(() {
                      _authStatus = AuthStatus.FAIL_BIOMETRICS_AUTH;
                    })
                  }
            });
      }
    }
  }

  @override
  dispose() {
    super.dispose();
    animationController.dispose();
  }

}
